package model;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Classe representant une conversation TCP
 * @author Lefevre, Thoue
 */
public class Conversation extends Thread {

    private Socket socketClient; // recevra le socket liant au client
    private ObjectOutputStream out; // pour gestion du flux de sortie
    private ObjectInputStream in; // pour gestion du flux d'entree
    private Serveur serveur; // pour utilisation des methodes de la classe principale
    private int idClient = 0; // contiendra le numero de client gerepar ce thread
    private boolean running = true;
    private User user;
    private EStatusConversation status;
    private boolean mute = false;
    private StringBuffer messagesChat;
    final static int taille = 640;
    /**
     * Constructeur
     * @param s socket du client tcp
     * @param serveur serveur tcp
     */
    public Conversation(Socket s, Serveur serveur) {
        this.socketClient = s;
        this.serveur = serveur;
        status = EStatusConversation.START;
        messagesChat = new StringBuffer();
        try {
            // fabrication d'une variable permettant l'utilisation du flux de sortie avec des string
            out = new ObjectOutputStream(socketClient.getOutputStream());
            // fabrication d'une variable permettant l'utilisation du flux d'entree avec des string
            in = new ObjectInputStream(socketClient.getInputStream());
            // ajoute le flux de sortie dans la liste et recuperation de son numero
            idClient = serveur.addClient(out);
        } catch (IOException e) {
            Logger.getLogger(Serveur.class.getName()).log(Level.SEVERE, "Erreur lors de la fabrication des flux in/out", e);
        }
    }
    /**
     * Methode principal du thread -
     * Change le status de la conversation en fonction du message recu.
     */
    @Override
    public void run() {
        Logger.getLogger(Serveur.class.getName()).log(Level.INFO, "Conversation TCP demarre.");
        try {
            while (running) {
                Signalisation response = null;
                if ((response = (Signalisation) in.readObject()) != null) {
                    if (response.getTagMessage().equals(EMessage.DEMAND.toString())) {
                        Logger.getLogger(Serveur.class.getName()).log(Level.INFO, "Client: TCP :demand recu.");
                        status = EStatusConversation.DEMANDE;
                        user = response.getUser();
                        user.setId(idClient);
                        serveur.getManager().addCall(user);
                    } else if (response.getTagMessage().equals(EMessage.ACCEPT.toString())) {
                        Logger.getLogger(Serveur.class.getName()).log(Level.INFO, "Client: TCP :accept recu.");
                        status = EStatusConversation.ACCEPT;
                        user = response.getUser();
                        user.setId(idClient);
                        serveur.getManager().addCallAccepter(user);
                    } else if (response.getTagMessage().equals(EMessage.CONFIRM.toString())) {
                        Logger.getLogger(Serveur.class.getName()).log(Level.INFO, "Client: TCP :confirm recu.");
                        status = EStatusConversation.ETABLISH;
                        serveur.getManager().addCallActive(user);
                        serveur.getManager().setUserChatActif(user);
                        serveur.getManager().demarrerSon();
                    } else if (response.getTagMessage().equals(EMessage.PAUSE.toString())) {
                        Logger.getLogger(Serveur.class.getName()).log(Level.INFO, "Client: TCP :pause recu.");
                        status = EStatusConversation.PAUSE;
                         serveur.getManager().miseEnPause(user,true);
                    } else if (response.getTagMessage().equals(EMessage.REPRISE.toString())) {
                        status = EStatusConversation.ETABLISH;
                         serveur.getManager().miseEnPause(user,false);
                        Logger.getLogger(Serveur.class.getName()).log(Level.INFO, "Client: TCP :reprise recu.");
                    } else if (response.getTagMessage().equals(EMessage.MESSAGE.toString())) {
                        Logger.getLogger(Serveur.class.getName()).log(Level.INFO, "Client: TCP :message recu.");
                        messagesChat.append(user.getNom());
                        messagesChat.append(" ");
                        messagesChat.append(user.getPrenom());
                        messagesChat.append(":");
                        messagesChat.append(response.getMessage());
                        messagesChat.append("\n");
                        serveur.getManager().rafraichirvue();
                    } else if (response.getTagMessage().equals(EMessage.FIN.toString())) {
                        Logger.getLogger(Serveur.class.getName()).log(Level.INFO, "Client: TCP :fin recu.");
                        status = EStatusConversation.FIN;
                        running = false;
                        serveur.deleteClient(idClient);
                    }
                }
            }
        } catch (IOException ex) {
            status = EStatusConversation.FIN;
            serveur.deleteClient(idClient);
            Logger.getLogger(Conversation.class.getName()).log(Level.INFO, "le client s'est arrete");
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Conversation.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            socketClient.close();
        } catch (IOException ex1) {
            Logger.getLogger(Conversation.class.getName()).log(Level.SEVERE, null, ex1);
        }
    }
    /**
     * Setter running
     * @param running vrai si le thread est actif
     */
    public void setRunning(boolean running) {    this.running = running;    }
    /**
     * Getter serveur
     * @return le serveur TCP
     */
    public Serveur getServeur() {    return serveur;   }
    /**
     * Getter socketClient
     * @return la socket du client TCP
     */
    public Socket getSocketClient() {    return socketClient;    }
    /**
     * Getter status
     * @return le status (etat) de la conversation
     */
    public EStatusConversation getStatus() {    return status;    }
    /**
     * Setter status
     * @param status le status (etat) de la conversation
     */
    public void setStatus(EStatusConversation status) {  this.status = status;    }
    /**
     * Getter user
     * @return utilisateur destinataire de la conversation
     */
    public User getUser() {    return user;    }
    /**
     * Setter user
     * @param user utilisateur destinataire de la conversation
     */
    public void setUser(User user) {    this.user = user;   }
    /**
     * Getter idClient
     * @return identifiant de la conversation
     */
    public int getIdClient() {    return idClient;    }
    /**
     * Setter idClient
     * @param idClient identifiant de la conversation
     */
    public void setIdClient(int idClient) {  this.idClient = idClient;    }
    /**
     * Getter messagesChat
     * @return l'historique du chat de la conversation
     */
    public StringBuffer getMessagesChat() {   return messagesChat;    }
    /**
     * Observateur mute
     * @return vrai si la conversation a le son couper
     */
    public boolean isMute() {   return mute;    }
    /**
     * Setter mute
     * @param mute vrai si la conversation a le son couper
     */
    public void setMute(boolean mute) {    this.mute = mute;    }    
}